﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using Dapper.Contrib.Extensions;
using hello.csharp.common.Interfaces;
using hello.csharp.common.Interfaces.Storages;
using hello.csharp.domain;
using hello.csharp.domain.Base;
using hello.csharp.helper;
using hello.csharp.helper.Enums;
using hello.csharp.storage.Db;
using NLog;

namespace hello.csharp.storage
{
    public class UserStorageWrite : IUserStorageWrite
    {
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();
        private readonly IDbManager _dbManager;
        private readonly SqlBox _sqlBox;

        public UserStorageWrite(IDbManager dbManager, IDbInitialise dbInit)
        {
            _dbManager = dbManager;
#if DEBUG
            var dbType = DatabaseType.SqLite;
#else
            var dbType = DatabaseType.PostgreSql;
#endif
            _sqlBox = dbInit.SqlSets[dbType];
        }

        /// <summary>
        /// 当前实现面向的数据表表名
        /// </summary>
        public string TableName { get; } = $"{nameof(User)}s";

        /// <inheritdoc />
        public async Task InsertAsync(User user)
        {
            var conn = _dbManager.OpenWriteConnection();
            var sql = _sqlBox.Insert[nameof(User)];
            await conn.ExecuteAsync(sql, user);
        }

        /// <inheritdoc />
        public async Task UpdateAsync(User user)
        {
            var conn = _dbManager.OpenWriteConnection();
            await conn.UpdateAsync(user);
        }

        /// <inheritdoc />
        public async Task LogicDeleteAsync(string id)
        {
            var conn = _dbManager.OpenWriteConnection();
            var sql = $"UPDATE {TableName} SET {nameof(User.State)}={(short)RecordState.Deleted} WHERE {nameof(IDomain.Id)}='{id}'";
            await conn.ExecuteAsync(sql);
        }

        /// <inheritdoc />
        public async Task RemoveAsync(string id)
        {
            var conn = _dbManager.OpenWriteConnection();
            var sql = $"DELETE FROM {TableName} WHERE {nameof(IDomain.Id)}='{id}'";
            await conn.DeleteAsync(sql);
        }

        public async Task InsertManyAsync(User[] users)
        {
            var conn = _dbManager.OpenWriteConnection();
            var sql = _sqlBox.Insert[nameof(User)];
            await conn.ExecuteAsync(sql, users);
        }
    }
}
